<?php
// +----------------------------------------------------------------------
// | Created by Sublime: [ Conqweal ]
// +----------------------------------------------------------------------
// | Copyright (c) 2021~20223[chenjia] All rights reserved.
// +----------------------------------------------------------------------
// | SiteUrl: http://www.99dn.cn
// +----------------------------------------------------------------------
// | Author: Conqweal <150672834@qq.com>
// +----------------------------------------------------------------------
// | Date: 2021/12/22 0026
// +----------------------------------------------------------------------
// | Description:任务管理
// +----------------------------------------------------------------------


namespace app\admin\controller;
use app\BackendController;
use app\admin\model\Mission as cmodel;
use think\facade\Cache;
use support\Request;
use think\facade\Db;
use Webman\Config;
use support\Util\InitTree;
class MissionController extends BackendController
{

    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index()
    {


        $cat_options    = $this->getCats([]);
        $status         = cmodel::getStatus();
        $status_options = output_select($status, []);
        return view('mission/index', compact('cat_options', 'status_options'));
    }

    /**
     * 显示过期列表
     *
     * @return \think\Response
     */
    public function expired()
    {

        $cat_options    = $this->getCats([]);
        $status         = cmodel::getStatus();
        $status_options = output_select($status, []);
        return view('mission/expired', compact('cat_options', 'status_options'));
    }

    /**
     * 过期处理
     * @return [type] [description]
     */
    public function doExpired(Request $request)
    {
        Db::startTrans();
        try {
            $ids = $request->get('id');
            $ls  = cmodel::with('description')->whereRaw("create_time  <= UNIX_TIMESTAMP()-days_expire*86400 and status<4 ")->where('mission_id', 'in', $ids)->select();

            foreach ($ls as $item) {
                $item->save(['status' => 4, 'remark' => __('系统自动结算并关闭')]);
                $this->dealCompleteMoney($item);
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return $this->error($e->getMessage());
        }
        return  $this->success(__('Operation successful'));
    }

    /**
     * 列表json数据
     * @param  Request $request [请求变量]
     * @return [type]           [json数据]
     */
    public function listDataExpired(Request $request)
    {   

        $limit = $request->get('limit', 10);
        $sort  = $request->get("sort", 'mission_id');
        $order = $request->get("order", "DESC");

        $w = [];

        if ($request->get('title')) {
            $w[] = ['b.title|a.mission_no', 'like', '%' . $request->get('title') . '%'];

        }
        if ($request->get('mission_id')) {
            $w[] = ['a.mission_id', '=', $request->get('mission_id')];

        }
        if ($request->get('content')) {
            $w[] = ['b.content', 'like', '%' . $request->get('content') . '%'];

        }
        if ($request->get('req')) {
            $w[] = ['b.req', 'like', '%' . $request->get('req') . '%'];

        }

        if ($request->get('seo')) {
            $w[] = ['b.seo->meta_title|b.seo->meta_keyword|b.seo->meta_description', 'like', '%' . $request->get('seo') . '%'];

        }

        if ($request->get('cat_id')) {
            $w[] = ['a.cat_id', '=', $request->get("cat_id")];
        }
        $time = time();
        $q    = cmodel::alias('a')
            ->join("mission_description b", "a.mission_id=b.mission_id", 'left')
            ->field("a.*,b.title,b.content,b.req,b.seo")
            ->where('a.status', '<', '4')
            ->whereRaw('(a.create_time+a.days_expire*86400)<' . $time)

            ->where($w)->order($sort, $order);

        $ls = $q->paginate(['list_rows' => $limit, 'request' => $request->all()]);

        $res    = $ls->items();
        $status = cmodel::getStatus();
        $ids    = [];
        $res    = array_map(function ($v) use ($status, &$ids) {
            $v->content = msubstr($v->content,0,30);
            $v->cat_name   = $v->cat_info[0]->cat_name;
            $v->status_txt = $status[$v->status];
            $v->user_info  = $v->user_info;
            $v->profile    = $v->user_info->profile;
            $ids[]         = $v->mission_id;
            return $v;
        }, $res);
        $stats =  $partics=[];       
        if($ids){            
            //交稿，采纳统计
            $stats = Db::name("mission_schedule")->where('mission_id', 'in', $ids)->group("mission_id")->field("sum(if(status=1,1,0)) as user_sub,sum(if(status=2,1,0)) as user_adopt,sum(if(status=3,1,0)) as user_win,mission_id")->select()->toArray();
            $stats = array_column($stats, null, "mission_id");
            //报名统计

            $partics = Db::name("mission_sign")->where('mission_id', 'in', $ids)->group("mission_id")->column("sum(1) as user_partic", "mission_id");
        }

        $res = array_map(function ($v) use ($stats, $partics) {           
            $v->user_partic = $partics[$v->mission_id];
            $v->user_adopt  = $stats[$v->mission_id]['user_adopt'];
            $v->user_sub    = $stats[$v->mission_id]['user_sub'];
            $v->user_win    = (int) $stats[$v->mission_id]['user_win'];
            return $v;
        }, $res);
        return json(['code' => $ls->total() > 0 ? 0 : 201, 'msg' => '无数据', 'count' => $ls->total(), 'data' => $res]);
    }
    /**
     * 列表json数据
     * @param  Request $request [请求变量]
     * @return [type]           [json数据]
     */
    public function listData(Request $request)
    {
        $limit = $request->get('limit', 10);
        $sort  = $request->get("sort", 'mission_id');
        $order = $request->get("order", "DESC");
        $now   = time();

        $w = [];

        if ($request->get('title')) {
            $w[] = ['b.title|a.mission_no', 'like', '%' . $request->get('title') . '%'];

        }
        if ($request->get('content')) {
            $w[] = ['b.content', 'like', '%' . $request->get('content') . '%'];

        }
        if ($request->get('u_id')) {
            $w[] = ['a.u_id', '=', $request->get('u_id')];

        }

        if ($request->get('status')) {
            if($request->get('status')=="-1"){
                $w[] = ['a.delete_time', '>', 0];
            }else{
                $w[] = ['a.status', '=', $request->get('status')];
            }

        }

        if ($request->get('seo')) {
            $w[] = ['b.seo->meta_title|b.seo->meta_keyword|b.seo->meta_description', 'like', '%' . $request->get('seo') . '%'];

        }

        if ($request->get('cat_id')) {
            $w[] = ['a.cat_id', '=', $request->get("cat_id")];
        }

        $q = cmodel::alias('a')
            ->join("mission_description b", "a.mission_id=b.mission_id", 'left')
            ->field("a.*,b.title,b.content,b.req,b.seo,b.language_id")
            ->where($w)->order($sort, $order);

        $ls = $q->paginate(['list_rows' => $limit, 'request' => $request->all()]);

        $res    = $ls->items();
        $status = cmodel::getStatus();
        $ids    = [];
        $res    = array_map(function ($v) use ($status, &$ids, $now) {
            $v->content = msubstr($v->content,0,30);
            $v->cat_name     = $v->cat_info[0]->cat_name;
            $v->status_txt   = $status[$v->status];
            $v->user_info    = $v->user_info;
            $v->profile      = $v->user_info->profile;
            $v->expired      = ($v->getData('create_time') + $v->days_expire * 86400) < $now;
            $ids[]           = $v->mission_id;
            $v->lang_txt     = getLangs()[$v->language_id];
            $v->LAY_DISABLED = ($v->status != 2 ||$v->expired) ? 1 : 0;
            $v->route = createUrl('task',$v->title,$v->mission_id);
            return $v;
        }, $res);

        //交稿，采纳统计
        $stats = Db::name("mission_schedule")->where('mission_id', 'in', $ids)->group("mission_id")->field("sum(if(status=1,1,0)) as user_sub,sum(if(status=2,1,0)) as user_adopt,sum(if(status=3,1,0)) as user_win,mission_id")->select()->toArray();
        $stats = array_column($stats, null, "mission_id");
        //报名统计

        $partics = Db::name("mission_sign")->where('mission_id', 'in', $ids)->group("mission_id")->column("sum(1) as user_partic", "mission_id");

        //评论统计
        $comments = Db::name("mission_comments")->where('reply_id','>',0)->where('mission_id', 'in', $ids)->group("mission_id")->column("sum(1) as t", "mission_id");
       
        $res = array_map(function ($v) use ($stats, $partics,$comments) {
            $v->user_partic = $partics[$v->mission_id];
            $v->user_adopt  = $stats[$v->mission_id]['user_adopt'];
            $v->user_sub    = $stats[$v->mission_id]['user_sub'];
            $v->user_win    = $stats[$v->mission_id]['user_win'];
            $v->user_comment    = (int)$comments[$v->mission_id];
            return $v;
        }, $res);
         
        return json(['code' => $ls->total() > 0 ? 0 : 201, 'msg' => '无数据', 'count' => $ls->total(), 'data' => $res]);
    }

    /**
     * 显示编辑资源表单页.
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function edit(Request $request)
    {
        $id  = $request->get("id");
        $data = cmodel::with("description")->find($id);

        $sel = [$data->cat_id];

        $cat_options    = $this->getCats($sel);
        $langs          = getLangs();
        $description    = $data->description;
        $status         = cmodel::getStatus();
        $status_options = output_select($status, $data->status);
        return view('mission/edit', compact('data', 'cat_options', 'langs', 'description', 'status_options'));
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request  $request
     * @param  int  $id
     * @return \think\Response
     */
    public function update(Request $request)
    {
        $id= $request->get("id");
        $post = $request->post();
       
        $valid = new \app\admin\validate\Mission;
        $r     = $valid->check($post);

        $cmodel            = new cmodel;
        $info              = $cmodel->where('mission_id', $id)->find();
        $info->cat_id      = $post['cat_id'];
        $info->description = $post['description'];
        $info->together(['description'])->save();

        $msg = ['status' => 1, 'msg' => '保存成功'];

        return json($msg);

    }

    /**
     * 批量审核
     * @return [type] [description]
     */
    public function batchverify(Request $request)
    {
        $ids = $request->get('id');
        $t1  = count(explode(',', $ids));
        $t2  = cmodel::where('mission_id', 'in', $ids)->where('status', 2)->whereRaw("create_time  > UNIX_TIMESTAMP()-days_expire*86400")->save(['status' => 3]);

        return json(['status' => 1, 'msg' => '审核结果,成功' . $t2 . '个' . '，失败' . ($t1 - $t2) . '个']);
    }

    /**
     * 自动完成时款项处理
     * @param  [type] $info [description]
     * @return [type]       [description]
     */
    private function dealCompleteMoney($info)
    {

        $total = Db::name("user_money_log")->where('u_id', $info->u_id)->where('op_type', 3)->where('op_key', $info->mission_id)->value('reduce');

        if (!$total) {
            throw new \Exception("任务付款记录丢失");
        }

        $cfg        = $info->money_cfg;
        $prize_mode = $cfg['slt_bid_mode'];

        $has;
        if ($prize_mode == 1) {
            $has[1] = [1, $total];
        } elseif ($prize_mode == 2) {
            $has[1] = [(int) $cfg['txt_pople_1'], (int) $cfg['txt_avg_money_1']];
            $has[2] = [(int) $cfg['txt_pople_2'], (int) $cfg['txt_avg_money_2']];
            $has[3] = [(int) $cfg['txt_pople_3'], (int) $cfg['txt_avg_money_3']];
        } elseif ($prize_mode == 3) {
            $has[1] = [(int) $cfg['gj_num'], (int) $cfg['gj_money']];
        }
        $moneys = [];
        if ($info->contributesEffect && !$info->contributesEffect->isEmpty()) {
            //需要结算
            $contributes = $info->contributesEffect->toArray();

            $data = [];

            foreach ((array) $contributes as $v) {
                if ($v['status'] != 3) {
                    continue;
                }
                $level = (int) $v['prize_level'] > 0 ? $v['prize_level'] : 1;
                if ($data[$level] < $has[$level][0]) {
                    $data[$level]++;
                    $v['money'] = $has[$level][1];
                    $moneys[]   = ['u_id' => $v['u_id'], 'plus' => $v['money'], 'op_type' => 4, 'op_key' => $v['id']];
                }

            }
            //实际任务金额
            $money_actual = array_sum(array_column($moneys, 'plus'));
            $this->updateScheduleMoney($total, $moneys);
            $info->save(['money_actual' => $money_actual]);
            $refund = $info->money - $money_actual;
            $this->refundMoney($info, $refund, '部分退回');
        } else {
            //退还款项
            $this->refundMoney($info, $total, '退回');

        }

        return true;

    }

    /**
     * 退还款项
     * @param  [type] $info  [description]
     * @param  [type] $total [description]
     * @return [type]        [description]
     */
    private function refundMoney($info, $total, $memo = '退回')
    {
        if ($total <= 0) {
            return;
        }
        //退还款项
        $time = time();

        $before = Db::name("user")->where('u_id', $info->u_id)->lock(true)->value('money');

        $data = [
            'u_id'        => $info->u_id,
            'plus'        => $total,
            'before'      => $before,
            'after'       => $before + $total,
            'memo'        => $memo,
            'create_time' => $time,
            'update_time' => $time,
            'op_type'     => 5,
            'op_key'      => $info->mission_id,
        ];
        $validate = new \app\admin\validate\MoneyLog;
        $result   = $validate->check($data);
        if (!$result) {
            throw new \Exception('参数存在问题');
        }

        Db::name("user_money_log")->insert($data);
        Db::name("user")->where('u_id', $info->u_id)->inc('money', $total)->update();
    }

    /**
     * 更新稿件款项
     * @param  [type] $moneys [description]
     * @return [type]         [description]
     */
    private function updateScheduleMoney($total, $moneys)
    {

        if (array_sum(array_column($moneys, 'plus')) > $total) {
            throw new \Exception(__("The total amount of manuscript payment exceeds the task reward amount"), 1);
        }
        $time = time();
        foreach ($moneys as $key => $value) {
            $before = Db::name('user')->where('u_id', $value['u_id'])->lock(true)->value('money');
            Db::name('user_money_log')->insert([
                'u_id'        => $value['u_id'],
                'plus'        => $value['plus'],
                'before'      => $before,
                'after'       => $before + $value['plus'],
                'op_type'     => $value['op_type'],
                'op_key'      => $value['op_key'],
                'create_time' => $time,
                'update_time' => $time,
            ]);
            Db::name('mission_schedule')->where('id', $value['op_key'])->update(['money' => $value['plus'], 'update_time' => $time]);
            Db::name('user')->where('u_id', $value['u_id'])->inc('money', $value['plus'])->update();
        }

        return true;

    }



    /**
     * 生成分类select列表
     * @param  [type] $sel [选中项]
     * @return [type]      [数组]
     */
    private function getCats($sel)
    {
        $lang_id = $this->lang_id;
        $menus = Db::name('cat')->alias('a')->join("cat_description b", 'a.cat_id=b.cat_id and b.language_id=' . $lang_id, 'left')->where('a.group', '任务')->column("a.cat_id as id,b.cat_name as name,a.pid as parentid,a.sorted as `order`", "a.cat_id");
       

        $tree  = new InitTree;
        $tree->set_tree($menus);

        $cat_options = $tree->get_tree_multi(0, "<option value=\$id \$selected>\$spacer\$name</option>", $sel);
        $cat_options = "<option value=''>请选择</option>" . $cat_options;
        return $cat_options;

    }


    /**
     * 假性删除，从任务大厅隐藏
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function delete(Request $request){
        $id=  $request->get("id");
        Db::name("mission")->where('mission_id',$id)->useSoftDelete('delete_time',time())->delete();
        $data['status'] = 1;
        $data['msg'] = '删除成功';
        return json($data);
    }

}
